/*****************************************************************************
*
* Copyright (c) 2000 - 2012, Lawrence Livermore National Security, LLC
* Produced at the Lawrence Livermore National Laboratory
* LLNL-CODE-442911
* All rights reserved.
*
* This file is  part of VisIt. For  details, see https://visit.llnl.gov/.  The
* full copyright notice is contained in the file COPYRIGHT located at the root
* of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html.
*
* Redistribution  and  use  in  source  and  binary  forms,  with  or  without
* modification, are permitted provided that the following conditions are met:
*
*  - Redistributions of  source code must  retain the above  copyright notice,
*    this list of conditions and the disclaimer below.
*  - Redistributions in binary form must reproduce the above copyright notice,
*    this  list of  conditions  and  the  disclaimer (as noted below)  in  the
*    documentation and/or other materials provided with the distribution.
*  - Neither the name of  the LLNS/LLNL nor the names of  its contributors may
*    be used to endorse or promote products derived from this software without
*    specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR  IMPLIED WARRANTIES, INCLUDING,  BUT NOT  LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE
* ARE  DISCLAIMED. IN  NO EVENT  SHALL LAWRENCE  LIVERMORE NATIONAL  SECURITY,
* LLC, THE  U.S.  DEPARTMENT OF  ENERGY  OR  CONTRIBUTORS BE  LIABLE  FOR  ANY
* DIRECT,  INDIRECT,   INCIDENTAL,   SPECIAL,   EXEMPLARY,  OR   CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT  LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR
* SERVICES; LOSS OF  USE, DATA, OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER
* CAUSED  AND  ON  ANY  THEORY  OF  LIABILITY,  WHETHER  IN  CONTRACT,  STRICT
* LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY  WAY
* OUT OF THE  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
*****************************************************************************/

// ************************************************************************* //
//                            avtSCHISMFileFormat.C                           //
// ************************************************************************* //

#include <avtSCHISMFileFormat.h>

#include <string>
#include <iostream>
#include <sstream>
#include <time.h>
#include <math.h>

#include <vtkDoubleArray.h>
#include <vtkFloatArray.h>
#include <vtkRectilinearGrid.h>
#include <vtkRectilinearGrid.h>
#include <vtkUnstructuredGrid.h>
#include <vtkSmartPointer.h>
#include <vtkCellArray.h>
#include <vtkPolyhedron.h>
#include <vtkPlaneSource.h>
#include <vtkMath.h>
#include <vtkPoints.h>
#include <vtkCellType.h> 

#include <avtDatabaseMetaData.h>
#include <avtVariableCache.h>

#include <DBOptionsAttributes.h>
#include <Expression.h>

#include <InvalidVariableException.h>
#include <InvalidDBTypeException.h>
#include <InvalidTimeStepException.h>
#include <InvalidFilesException.h>
#include <DBYieldedNoDataException.h>
#include <DebugStream.h>
//L3 #include <malloc.h>
#if defined(__MACH__)
#include <stdlib.h>
#else
#include <malloc.h>
#endif

#include "netcdfcpp.h"
#include "FileFormatFavorFactory.h"


// ****************************************************************************
//  Method: avtSCHISMFileFormat constructor
//
//  Programmer: qshu -- generated by xml2avt
//  Creation:   Wed Mar 13 09:13:49 PDT 2013
//
// ****************************************************************************

avtSCHISMFileFormat::avtSCHISMFileFormat(const char *filename)
    : avtMTSDFileFormat(&filename, 1),
	  m_data_file(filename)
{
  
	//based on file type reset m_impl to proper implementation favor
	NcFile*           outputNcFilePtr = new NcFile(filename,NcFile::ReadOnly);
	if (outputNcFilePtr->is_valid()==0)
	{
		m_impl.reset((FileFormatFavorFactory::Instance())->CreateInstance("native_binary"));
	}
	else
	{
		 m_impl.reset(FileFormatFavorFactory::Instance()->CreateInstance("combine10_nc4_double_xy"));
	}
}


// ****************************************************************************
//  Method: avtEMSTDFileFormat::GetNTimesteps
//
//  Purpose:
//      Tells the rest of the code how many timesteps there are in this file.
//
//  Programmer: qshu -- generated by xml2avt
//  Creation:   Wed Mar 13 09:13:49 PDT 2013
//
// ****************************************************************************

int
avtSCHISMFileFormat::GetNTimesteps(void)
{
  return m_impl->GetNTimesteps(m_data_file);
}




// ****************************************************************************
//  Method: avtSCHISMFileFormat::FreeUpResources
//
//  Purpose:
//      When VisIt is done focusing on a particular timestep, it asks that
//      timestep to free up any resources (memory, file descriptors) that
//      it has associated with it.  This method is the mechanism for doing
//      that.
//
//  Programmer: qshu -- generated by xml2avt
//  Creation:   Wed Mar 13 09:13:49 PDT 2013
//
// ****************************************************************************

void
avtSCHISMFileFormat::FreeUpResources(void)
{
   m_impl->FreeUpResources();
   
}

// ****************************************************************************
//  Method: avtSCHISMFileFormat::GetMesh
//
//  Purpose:
//      Gets the mesh associated with this file.  The mesh is returned as a
//      derived type of vtkDataSet (ie vtkRectilinearGrid, vtkStructuredGrid,
//      vtkUnstructuredGrid, etc).
//
//  Arguments:+
//      timestate   The index of the timestate.  If GetNTimesteps returned
//                  'N' time steps, this is guaranteed to be between 0 and N-1.
//      mesh_name    The name of the mesh of interest.  This can be ignored if
//                  there is only one mesh.
//
//  Programmer: qshu -- generated by xml2avt
//  Creation:   Wed Mar 13 09:13:49 PDT 2013
//
// ****************************************************************************

vtkDataSet *
avtSCHISMFileFormat::GetMesh(int a_timeState, const char *mesh_name)
{
	return m_impl->GetMesh(a_timeState,this,mesh_name);
}



// ****************************************************************************
//  Method: avtSCHISMFileFormat::GetVar
//
//  Purpose:
//      Gets a scalar variable associated with this file.  Although VTK has
//      support for many different types, the best bet is vtkFloatArray, since
//      that is supported everywhere through VisIt.
//
//  Arguments:
//      timestate  The index of the timestate.  If GetNTimesteps returned
//                 'N' time steps, this is guaranteed to be between 0 and N-1.
//      varname    The name of the variable requested.
//
//  Programmer: qshu -- generated by xml2avt
//  Creation:   Wed Mar 13 09:13:49 PDT 2013
//
// ****************************************************************************

vtkDataArray *
avtSCHISMFileFormat::GetVar(int a_timeState, const char *a_varName)
{

   return m_impl->GetVar(a_timeState,a_varName);
}


// ****************************************************************************
//  Method: avtSCHISMFileFormat::GetVectorVar
//
//  Purpose:
//      Gets a vector variable associated with this file.  Although VTK has
//      support for many different types, the best bet is vtkFloatArray, since
//      that is supported everywhere through VisIt.
//
//  Arguments:
//      timestate  The index of the timestate.  If GetNTimesteps returned
//                 'N' time steps, this is guaranteed to be between 0 and N-1.
//      varname    The name of the variable requested.
//
//  Programmer: qshu -- generated by xml2avt
//  Creation:   Wed Mar 13 09:13:49 PDT 2013
//
// ****************************************************************************

vtkDataArray *
avtSCHISMFileFormat::GetVectorVar(int a_timeState, const char *a_varName)
{
  return m_impl->GetVectorVar(a_timeState,a_varName);
}




// ****************************************************************************
//  Method: avtSCHISMFileFormat::ActivateTimestep
//
//  Purpose:
//      
//      
//  Programmer: qshu -- generated by xml2avt
//  Creation:   Mon Aug 6 09:53:36 PDT 2012
//
// ****************************************************************************

void  avtSCHISMFileFormat::ActivateTimestep()
{
	m_impl->ActivateTimestep(m_data_file);
}


// ****************************************************************************
//  Method: avtSCHISMFileFormat::GetTimes
//
//  Purpose:
//      overloaded public interface to return time steps
//      
//     
//
//  Programmer: qshu
//  Creation:   Mon Aug 15 03:02:00 PDT 2012
//
// ****************************************************************************
void   avtSCHISMFileFormat::GetTimes(std::vector<double> & a_times)
{
	m_impl->GetTimes(a_times);
}


 void avtSCHISMFileFormat::addMeshToMetaData(avtDatabaseMetaData * a_metaData, 
                         const std::string & a_mesh_name, 
                         const avtMeshType & a_mt, 
                         double           *  a_extents, 
                         const int        &  a_nblocks, 
                         const int        &  a_block_origin,
                         const int        &  a_spatial_dimension, 
                         const int        &  a_topological_dimension)
 {
	 AddMeshToMetaData(a_metaData, 
                       a_mesh_name, 
                       a_mt, 
                       a_extents, 
                       a_nblocks, 
                       a_block_origin,
                       a_spatial_dimension, 
                       a_topological_dimension);

 }


  void   avtSCHISMFileFormat::PopulateDatabaseMetaData(avtDatabaseMetaData * a_metaData, 
                                                       int                   a_timeState)
  {
	  m_impl->PopulateDatabaseMetaData(a_metaData, this,a_timeState);
  }

  
  void   avtSCHISMFileFormat::addScalarVarToMetaData(avtDatabaseMetaData * a_metaData, 
	                           const std::string & a_label,   
							   const std::string & a_mesh,
							   const avtCentering& a_center)
  {
	  AddScalarVarToMetaData(a_metaData, a_label, a_mesh, a_center);
  }

  void   avtSCHISMFileFormat::addVectorVarToMetaData(avtDatabaseMetaData * a_metaData,
	                           const std::string &  a_varLabel,
							   const std::string &  a_mesh,
							   const avtCentering&  a_center,
							   const int &          a_comps)
  {

	   AddVectorVarToMetaData(a_metaData,a_varLabel, a_mesh, a_center,a_comps);  
  }



    avtVariableCache * avtSCHISMFileFormat::get_cache()
	{
		return this->cache;
	}
